package vn.edu.hut.soict.alignment.ui;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;

import vn.edu.hut.soict.translate.database.TranslatorDatabase;

public class AlignmentUI extends JFrame implements ActionListener, MouseListener, KeyListener {
	private static final long serialVersionUID = 8030460859177161861L;

	private static final String DATABASE_MODE = "Database Mode";
	private static final String ADDING_MODE = "Adding Mode";

	private JPanel contentPane;
	private JTextField txtViSentence;
	private JTextField txtEnSentence;
	private JButton btnReset;
	private JButton btnNext;
	private JButton btnPrev;
	private JTextField txtAlignmentCode;
	private AlignmentPanel alignmentPanel;
	private JScrollPane scrollPane;
	private JButton btnMode;

	private TranslatorDatabase database;
	private ResultSet resultSet;

	private String viSentence = "";
	private String enSentence = "";
	private String alignmentCode = "";
	private JButton btnUpdate;
	private JButton btnAdd;
	private JButton btnDeleteAll;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					AlignmentUI frame = new AlignmentUI();
					frame.setVisible(true);
				}
				catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public AlignmentUI() {
		setTitle("C\u00F4ng c\u1EE5 gi\u00F3ng h\u00E0ng");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 988, 446);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(10, 10, 10, 10));
		setContentPane(contentPane);
		GridBagLayout gbl_contentPane = new GridBagLayout();
		gbl_contentPane.columnWidths = new int[] {
				130, 325, 0
		};
		gbl_contentPane.rowHeights = new int[] {
				20, 20, 0, 191, 0, 0, 0, 0, 0, 0
		};
		gbl_contentPane.columnWeights = new double[] {
				0.0, 1.0, 1.0
		};
		gbl_contentPane.rowWeights = new double[] {
				0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE
		};
		contentPane.setLayout(gbl_contentPane);

		JLabel lblViSentence = new JLabel("C\u00E2u ti\u1EBFng Vi\u1EC7t:");
		lblViSentence.setHorizontalAlignment(SwingConstants.RIGHT);
		GridBagConstraints gbc_lblViSentence = new GridBagConstraints();
		gbc_lblViSentence.fill = GridBagConstraints.HORIZONTAL;
		gbc_lblViSentence.insets = new Insets(0, 0, 5, 5);
		gbc_lblViSentence.gridx = 0;
		gbc_lblViSentence.gridy = 0;
		contentPane.add(lblViSentence, gbc_lblViSentence);

		txtViSentence = new JTextField();
		txtViSentence.addKeyListener(this);
		txtViSentence.setPreferredSize(new Dimension(15, 30));
		GridBagConstraints gbc_txtViSentence = new GridBagConstraints();
		gbc_txtViSentence.gridwidth = 3;
		gbc_txtViSentence.anchor = GridBagConstraints.NORTH;
		gbc_txtViSentence.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtViSentence.insets = new Insets(0, 0, 5, 0);
		gbc_txtViSentence.gridx = 1;
		gbc_txtViSentence.gridy = 0;
		contentPane.add(txtViSentence, gbc_txtViSentence);
		txtViSentence.setColumns(10);

		JLabel lblEnSentence = new JLabel("C\u00E2u ti\u1EBFng Anh:");
		lblEnSentence.setHorizontalAlignment(SwingConstants.RIGHT);
		GridBagConstraints gbc_lblEnSentence = new GridBagConstraints();
		gbc_lblEnSentence.fill = GridBagConstraints.HORIZONTAL;
		gbc_lblEnSentence.insets = new Insets(0, 0, 5, 5);
		gbc_lblEnSentence.gridx = 0;
		gbc_lblEnSentence.gridy = 1;
		contentPane.add(lblEnSentence, gbc_lblEnSentence);

		txtEnSentence = new JTextField();
		txtEnSentence.addKeyListener(this);
		txtEnSentence.setPreferredSize(new Dimension(15, 30));
		GridBagConstraints gbc_txtEnSentence = new GridBagConstraints();
		gbc_txtEnSentence.gridwidth = 3;
		gbc_txtEnSentence.anchor = GridBagConstraints.NORTH;
		gbc_txtEnSentence.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtEnSentence.insets = new Insets(0, 0, 5, 0);
		gbc_txtEnSentence.gridx = 1;
		gbc_txtEnSentence.gridy = 1;
		contentPane.add(txtEnSentence, gbc_txtEnSentence);
		txtEnSentence.setColumns(10);

		JLabel lblAlignment = new JLabel("Gi\u00F3ng h\u00E0ng:");
		lblAlignment.setHorizontalAlignment(SwingConstants.RIGHT);
		GridBagConstraints gbc_lblAlignment = new GridBagConstraints();
		gbc_lblAlignment.anchor = GridBagConstraints.NORTHEAST;
		gbc_lblAlignment.insets = new Insets(0, 0, 5, 5);
		gbc_lblAlignment.gridx = 0;
		gbc_lblAlignment.gridy = 2;
		contentPane.add(lblAlignment, gbc_lblAlignment);

		txtAlignmentCode = new JTextField();
		txtAlignmentCode.setEditable(false);
		txtAlignmentCode.setPreferredSize(new Dimension(15, 30));
		GridBagConstraints gbc_txtAlignmentCode = new GridBagConstraints();
		gbc_txtAlignmentCode.gridwidth = 3;
		gbc_txtAlignmentCode.insets = new Insets(0, 0, 5, 0);
		gbc_txtAlignmentCode.fill = GridBagConstraints.HORIZONTAL;
		gbc_txtAlignmentCode.gridx = 1;
		gbc_txtAlignmentCode.gridy = 2;
		contentPane.add(txtAlignmentCode, gbc_txtAlignmentCode);
		txtAlignmentCode.setColumns(10);

		btnReset = new JButton("Gi\u00F3ng l\u1EA1i");
		btnReset.addActionListener(this);

		scrollPane = new JScrollPane();
		GridBagConstraints gbc_scrollPane = new GridBagConstraints();
		gbc_scrollPane.fill = GridBagConstraints.BOTH;
		gbc_scrollPane.gridheight = 5;
		gbc_scrollPane.gridwidth = 3;
		gbc_scrollPane.insets = new Insets(0, 0, 5, 0);
		gbc_scrollPane.gridx = 1;
		gbc_scrollPane.gridy = 3;
		contentPane.add(scrollPane, gbc_scrollPane);

		alignmentPanel = new AlignmentPanel(viSentence, enSentence, alignmentCode);
		alignmentPanel.addMouseListener(this);
		scrollPane.setViewportView(alignmentPanel);

		btnMode = new JButton("Database Mode");
		btnMode.addActionListener(this);
		GridBagConstraints gbc_btnMode = new GridBagConstraints();
		gbc_btnMode.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnMode.insets = new Insets(0, 0, 5, 5);
		gbc_btnMode.gridx = 0;
		gbc_btnMode.gridy = 4;
		contentPane.add(btnMode, gbc_btnMode);
		GridBagConstraints gbc_btnReset = new GridBagConstraints();
		gbc_btnReset.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnReset.insets = new Insets(0, 0, 5, 5);
		gbc_btnReset.gridx = 0;
		gbc_btnReset.gridy = 5;
		contentPane.add(btnReset, gbc_btnReset);

		btnUpdate = new JButton("C\u1EADp nh\u1EADt");
		btnUpdate.setEnabled(false);
		btnUpdate.addActionListener(this);
		GridBagConstraints gbc_btnUpdate = new GridBagConstraints();
		gbc_btnUpdate.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnUpdate.insets = new Insets(0, 0, 5, 5);
		gbc_btnUpdate.gridx = 0;
		gbc_btnUpdate.gridy = 6;
		contentPane.add(btnUpdate, gbc_btnUpdate);

		btnAdd = new JButton("Th\u00EAm");
		btnAdd.addActionListener(this);
		GridBagConstraints gbc_btnAdd = new GridBagConstraints();
		gbc_btnAdd.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnAdd.insets = new Insets(0, 0, 5, 5);
		gbc_btnAdd.gridx = 0;
		gbc_btnAdd.gridy = 7;
		contentPane.add(btnAdd, gbc_btnAdd);

		btnPrev = new JButton("Tr\u01B0\u1EDBc");
		btnPrev.setEnabled(false);
		btnPrev.addActionListener(this);

		btnDeleteAll = new JButton("X\u00F3a to\u00E0n b\u1ED9");
		btnDeleteAll.addActionListener(this);
		GridBagConstraints gbc_btnDeleteAll = new GridBagConstraints();
		gbc_btnDeleteAll.fill = GridBagConstraints.HORIZONTAL;
		gbc_btnDeleteAll.insets = new Insets(0, 0, 0, 5);
		gbc_btnDeleteAll.gridx = 0;
		gbc_btnDeleteAll.gridy = 8;
		contentPane.add(btnDeleteAll, gbc_btnDeleteAll);
		GridBagConstraints gbc_btnPrev = new GridBagConstraints();
		gbc_btnPrev.insets = new Insets(0, 0, 0, 5);
		gbc_btnPrev.gridx = 1;
		gbc_btnPrev.gridy = 8;
		contentPane.add(btnPrev, gbc_btnPrev);

		btnNext = new JButton("Sau");
		btnNext.setEnabled(false);
		btnNext.addActionListener(this);
		GridBagConstraints gbc_btnNext = new GridBagConstraints();
		gbc_btnNext.insets = new Insets(0, 0, 0, 5);
		gbc_btnNext.gridx = 2;
		gbc_btnNext.gridy = 8;
		contentPane.add(btnNext, gbc_btnNext);

		initResources();
	}

	private void initResources() {
		database = new TranslatorDatabase();
		database.connect();
		resultSet = database.executeQueryWithConcurrentUpdate("SELECT * FROM " + database.getBilingualTableName());
	}

	private void fetchResult() {
		try {
			viSentence = resultSet.getString("vietnamese");
			enSentence = resultSet.getString("english");
			alignmentCode = resultSet.getString("align");
		}
		catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void updateContent() {
		txtViSentence.setText(viSentence);
		txtEnSentence.setText(enSentence);
		txtAlignmentCode.setText(alignmentCode);
		updateAlignmentPanel();
	}

	private void updateAlignmentPanel() {
		alignmentPanel = new AlignmentPanel(viSentence, enSentence, alignmentCode);
		alignmentPanel.addMouseListener(this);
		scrollPane.setViewportView(alignmentPanel);
		scrollPane.validate();
	}

	public void actionPerformed(ActionEvent arg0) {
		if (arg0.getSource() == btnMode) {
			do_btnMode_actionPerformed(arg0);
		}
		else if (arg0.getSource() == btnAdd) {
			do_btnAdd_actionPerformed(arg0);
		}
		else if (arg0.getSource() == btnUpdate) {
			do_btnUpdate_actionPerformed(arg0);
		}
		else if (arg0.getSource() == btnReset) {
			do_btnReset_actionPerformed(arg0);
		}
		else if (arg0.getSource() == btnDeleteAll) {
			do_btnDeleteAll_actionPerformed(arg0);
		}
		else if (arg0.getSource() == btnPrev) {
			do_btnPrev_actionPerformed(arg0);
		}
		else if (arg0.getSource() == btnNext) {
			do_btnNext_actionPerformed(arg0);
		}
	}

	protected void do_btnMode_actionPerformed(ActionEvent arg0) {
		if (btnMode.getText().equals(ADDING_MODE)) {
			btnMode.setText(DATABASE_MODE);
			btnNext.setEnabled(false);
			btnPrev.setEnabled(false);
			btnUpdate.setEnabled(false);
			btnAdd.setEnabled(true);

			viSentence = "";
			enSentence = "";
			alignmentCode = "";
			updateContent();
		}
		else if (btnMode.getText().equals(DATABASE_MODE)) {
			btnMode.setText(ADDING_MODE);
			btnNext.setEnabled(true);
			btnPrev.setEnabled(true);
			btnUpdate.setEnabled(true);
			btnAdd.setEnabled(false);
		}
	}

	protected void do_btnAdd_actionPerformed(ActionEvent arg0) {
		alignmentCode = alignmentPanel.alignmentCode();
		if (database.insertRowToBilingual(viSentence, enSentence, alignmentCode)) {
			JOptionPane.showMessageDialog(this, "Thêm thành công vào CSDL.", "Thông báo", JOptionPane.INFORMATION_MESSAGE);
		}
		else {
			JOptionPane.showMessageDialog(this, "Có lỗi xảy ra.", "Thông báo lỗi", JOptionPane.ERROR_MESSAGE);
		}
	}

	protected void do_btnUpdate_actionPerformed(ActionEvent arg0) {
		try {
			resultSet.updateString("vietnamese", viSentence);
			resultSet.updateString("english", enSentence);
			resultSet.updateString("align", alignmentPanel.alignmentCode());
			resultSet.updateRow();
		}
		catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	protected void do_btnReset_actionPerformed(ActionEvent arg0) {
		if (viSentence != null && !viSentence.isEmpty() && enSentence != null && !enSentence.isEmpty()) {
			alignmentCode = "";
			alignmentPanel = new AlignmentPanel(viSentence, enSentence, alignmentCode);
			updateContent();
		}
	}

	protected void do_btnDeleteAll_actionPerformed(ActionEvent arg0) {
		viSentence = "";
		enSentence = "";
		alignmentCode = "";
		updateContent();
	}

	protected void do_btnPrev_actionPerformed(ActionEvent arg0) {
		try {
			if (!resultSet.previous()) {
				resultSet.last();
			}
			fetchResult();
			updateContent();
		}
		catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	protected void do_btnNext_actionPerformed(ActionEvent arg0) {
		try {
			if (!resultSet.next()) {
				resultSet.first();
			}
			fetchResult();
			updateContent();
		}
		catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void mouseClicked(MouseEvent e) {
		if (e.getSource() == alignmentPanel) {
			do_alignmentPanel_mouseClicked(e);
		}
	}

	public void mouseEntered(MouseEvent e) {

	}

	public void mouseExited(MouseEvent e) {

	}

	public void mousePressed(MouseEvent e) {

	}

	public void mouseReleased(MouseEvent e) {

	}

	protected void do_alignmentPanel_mouseClicked(MouseEvent e) {
		txtAlignmentCode.setText(alignmentPanel.alignmentCode());
	}

	public void keyPressed(KeyEvent arg0) {

	}

	public void keyReleased(KeyEvent arg0) {
		viSentence = txtViSentence.getText();
		enSentence = txtEnSentence.getText();
		alignmentCode = "";
		updateAlignmentPanel();
	}

	public void keyTyped(KeyEvent arg0) {

	}

}
